<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>axios入门与源码解析</title>
  <link rel="stylesheet" href="../bootstrap.min.css">
  <!-- <script src="../axios.js"></script> -->
</head>

<body>
  <div class="container">
    <h2>axios基本使用</h2>
    <button class="btn btn-primary">发送GET请求</button>
    <button class="btn btn-warning">取消请求</button>
  </div>
  <script>
    // 构造函数
    function Axios(config) {
      this.config = config
    }
    // 原型的request方法
    Axios.prototype.request = function (config) {
      return dispatchRequest(config)
    }
    // dispatchRequest方法
    function dispatchRequest(config) {
      return xhrAdapter(config)
    }
    // xhrAdapter
    function xhrAdapter(config) {
      // 发送ajax请求
      return new Promise((resolve, reject) => {
        // 实例化对象
        // 发情ajax请求
        const xhr = new XMLHttpRequest()
        // 初始化
        xhr.open(config.method, config.url)
        // 发送
        xhr.send()
        // 绑定事件
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
            // 判断成功条件
            if (xhr.status >= 200 && xhr.status < 300) {
              resolve({
                // 响应状态码
                status: xhr.status,
                // 响应状态字符串
                statusText: xhr.statusText
              })
            } else {
              reject(new Error('请求失败 状态码为：' + xhr.status))
            }
          }
        }
        // 关于取消请求的处理
        if(config.cancelToken){
          // 对cancelToken对象身上的promise对象指定成功的回调
          config.cancelToken.promise.then(value=>{
            xhr.abort()
          })
        }
      })
    }
    // 创建axios
    const context = new Axios({})
    const axios = Axios.prototype.request.bind(context)
    
    // CancelToken构造函数
    function CancelToken(excutor){
      // 声明一个变量
      var resolvePromise;
      // 为实例对象添加属性
      this.promise = new Promise((resolve)=>{
        // 将resolve赋值给resolvePromise
        resolvePromise = resolve
      })
      // 调用excutor函数
      excutor(function(){
        // 执行resolvePromise
        resolvePromise()
      })
    }

    // 获取按钮
    const btns = document.querySelectorAll('button')
    // 2、声明全局变量
    let cancel = null;
    // 发送请求
    btns[0].onclick = function () {
      if (cancel !== null) {
        // 取消上一次请求
        cancel()
      }
      // 创建cancelToken的值
      let cancelToken = new CancelToken(function (c) {
        cancel = c
      })

      axios({
        method: 'get',
        url: 'http://localhost:3000/posts',
        // 1、添加配置对象的属性
        cancelToken: cancelToken
      }).then(res => {
        console.log(res)
        // 将cancel的值初始化
        cancel = null
      })
    }

    btns[1].onclick = function () {
      cancel()
    }
  </script>
</body>

</html>